﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;
namespace Gobang
{
    public partial class Landlord : Form
    {
        private Client clientProxy;
        public Landlord()
        {
            InitializeComponent();
            clientProxy = new Client();
            clientProxy.m_requestHandler += HandleMsg;
            bool res = clientProxy.Connect("127.0.0.1", 1009);
            //bool res = clientProxy.Connect("47.103.69.4", 1009);
            if (!res)
            {
                Debug.WriteLine("Connect Server failed");
                labelInfo.Text = "连接服务器失败";
            }
        }
        private void Landlord_Load(object sender, EventArgs e)
        {
            btnCallLord.Visible = false;
            btnUnCall.Visible = false;
            btnDiscard.Visible = false;
            btnNoDiscard.Visible = false;
        }
        private void HandleMsg(object[] args)
        {
            List<object> Args = new List<object>(args);
            if (args[0].GetType() != typeof(string))
            {
                Debug.WriteLine("first argument should be string");
                return;
            }
            string funcname = args[0] as string;
            Args.RemoveAt(0);
            MethodInfo minfo = this.GetType().GetMethod(funcname);
            if (minfo != null)
            {
                try
                {
                    minfo.Invoke(this, Args.ToArray());
                    Debug.WriteLine("ClientTool::" + funcname + " executed.");
                }
                catch (TargetParameterCountException e)
                {
                    Debug.WriteLine("ClientTool::" + funcname + " execute error: " + e.Message);
                }
                catch (TargetInvocationException e)
                {
                    Debug.WriteLine("ClientTool::" + funcname + " execute error: " + e.Message);
                }
            }
            else
            {
                Debug.WriteLine("ClientTool::" + funcname + " not found.");
            }
        }

        private void btnPrepare_Click(object sender, EventArgs e)
        {
            clientProxy.SendParams("READY", 1);
        }

        private void btnCallLord_Click(object sender, EventArgs e)
        {
            clientProxy.SendParams("CALL_LORD", 1);
            btnCallLord.Visible = false;
            btnUnCall.Visible = false;
        }
        public PokerCard Create_Card(int num, int offsetX, int offsetY)
        {
            PokerCard c = PokerCard.FromInt(num,offsetX,offsetY);
            this.Controls.Add(c);
            return c;
        }
        private void ClearCardInternal(Panel p)
        {
            List<Control> L = new List<Control>();
            foreach (Control c in p.Controls)
            {
                if (c.GetType() == typeof(PokerCard))
                {
                    L.Add(c);
                }
            }
            foreach (Control c in L)
            {
                p.Controls.Remove(c);
            }
        }
        private void ShowCardInternal(string cardStr, Panel p)
        {
            ClearCardInternal(p);
            string[] cards = cardStr.Split(',');
            int dx = p.Height / 9;
            int offsetx = p.Width / 2 - cards.Length / 2 * dx;
            int y = 0;
            foreach (string s in cards)
            {
                int num = int.Parse(s);
                PokerCard c = Create_Card(num, offsetx, y);
                p.Controls.Add(c);
                c.Parent = p;
                c.BringToFront();
                offsetx += dx;
                c.ResizeHeight(p.Height);
            }
        }
        public void DISPATCH_CARDS(string cardStr)
        {
            ShowCardInternal(cardStr, panelMyCards);
        }
        public void REVEAL_LORD_CARDS(string lordStr)
        {
            ShowCardInternal(lordStr, panelLordCards);
        }
        public void GAME_START()
        {
            btnPrepare.Visible = false;
        }
        public void GAME_OVER()
        {
            btnPrepare.Visible = true;
        }
        public void RECEIVE_MY_CALL(int leftTime)
        {
            btnCallLord.Visible = true;
            btnUnCall.Visible = true;
            labelLeftTime.Visible = true;
            labelLeftTime.Text = string.Format("{0}", leftTime);
        }
        public void TIMEOUT_MY_CALL()
        {
            btnCallLord.Visible = false;
            btnUnCall.Visible = false;
            labelLeftTime.Visible = false;
        }
        public void DISCARD_REJECT()
        {
            labelInfo.Text = "不符合规则";
        }
        public void TIMEOUT_MY_TURN()
        {
            btnDiscard.Visible = false;
            btnNoDiscard.Visible = false;
            labelLeftTime.Visible = false;
        }
        public void RECEIVE_MY_DISCARD(int leftTime)
        {
            ClearCardInternal(panelMyOutCards);
            btnDiscard.Visible = true;
            btnNoDiscard.Visible = false;
            labelLeftTime.Visible = true;
            labelLeftTime.Text = string.Format("{0}", leftTime);
        }
        public void RECEIVE_MY_TURN(int leftTime)
        {
            ClearCardInternal(panelMyOutCards);
            btnDiscard.Visible = true;
            btnNoDiscard.Visible = true;
            labelLeftTime.Visible = true;
            labelLeftTime.Text = string.Format("{0}", leftTime);
        }
        public void SHOW_DISCARD(string card, int pos)
        {
            if (pos == 0)
            {
                ShowCardInternal(card, panelMyOutCards);
            }
            else if (pos == -1)
            {
                ShowCardInternal(card, panelPreOutCards);
            }
            else if (pos == 1)
            {
                ShowCardInternal(card, panelNextOutCards);
            }
        }
        public void RECOGNIFY_DISCARD(string card)
        {
            btnDiscard.Visible = false;
            btnNoDiscard.Visible = false;
            labelLeftTime.Visible = false;
            List<Control> wL = new List<Control>();
            foreach (Control c in panelMyCards.Controls)
            {
                if (c.GetType() == typeof(PokerCard))
                {
                    PokerCard k = c as PokerCard;
                    if (card.Contains(k.ToInt().ToString()))
                    {
                        wL.Add(c);
                    }
                }
            }
            foreach (Control c in wL)
            {
                panelMyCards.Controls.Remove(c);
            }
            MakeCardsAlign(panelMyCards);
        }
        private void MakeCardsAlign(Panel p)
        {
            if (p.Controls.Count == 0)
                return;
            for (int i=0; i< p.Controls.Count; ++i)
            {
                PokerCard c = p.Controls[i] as PokerCard;
                Point LU = c.Location;
                int dx = c.Height / 9;
                //先add的在Controls的末尾
                int X = p.Width / 2 + (p.Controls.Count / 2 - i) * dx;
                c.Location = new Point(X, LU.Y);
                p.BringToFront();
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            clientProxy.m_client.Tick();
        }

        private void btnUnCall_Click(object sender, EventArgs e)
        {
            clientProxy.SendParams("CALL_LORD", 0);
            btnCallLord.Visible = false;
            btnUnCall.Visible = false;
        }

        private void btnDiscard_Click(object sender, EventArgs e)
        {
            string cardStr = "";
            foreach (Control c in panelMyCards.Controls)
            {
                if (c.GetType() == typeof(PokerCard))
                {
                    PokerCard card = c as PokerCard;
                    if (card.bChosen)
                    {
                        cardStr += card.ToInt().ToString();
                        cardStr += ",";
                    }
                }
            }
            if (cardStr.Length == 0)
            {
                labelInfo.Text = "未选择卡牌";
            }
            else
            {
                labelInfo.Text = "";
                string ret = cardStr.Remove(cardStr.Length - 1);
                clientProxy.SendParams("DISCARD", ret);
            }
        }

        private void btnNoDiscard_Click(object sender, EventArgs e)
        {
            btnDiscard.Visible = false;
            btnNoDiscard.Visible = false;
            labelLeftTime.Visible = false;
            labelInfo.Text = "";
            clientProxy.SendParams("DISCARD", "");
        }
    }
}
